/*
Copyright 2010 Iain Surgey.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
#__body__

private var alias_visible : Bool;

private function render_main() {
	
	R_Init();
	Mod_LoadAliasModel("knight");
	LoadBSP("basemap");
	LoadImages();
}

private function render_main2() {
	R_InitSkyBox();
	InitInput();
	
	__m__.length += 1024;
	
	R_RenderFrame();
	
	Con_Printf(PRINT_ALL,"Running..");
}

/*
===============
R_Init
===============
*/
private function R_Init()
{
	bmd = new BitmapData(RESH,RESV,false,0);
	bmp = new Bitmap(bmd);
	flash.Lib.current.stage.addChild(bmp);
	
	txformat = new flash.text.TextFormat();
	txformat.font = "Arial";
	txformat.size = 12;
	txformat.color=0xFFFFFF;
	scrtxt = new flash.text.TextField();
	scrtxt.text = 'HaXe3D';
	scrtxt.setTextFormat(txformat);
	scrtxt.x = 5;
	scrtxt.y = 5;
	scrtxt.width = RESH-scrtxt.x;
	scrtxt.height = RESV-scrtxt.y;
	scrtxt.selectable = false;
	flash.Lib.current.stage.addChild(scrtxt);
	
	scrtxt.text = "hxQuake\nFPS: 0";
	write("\nMove: W, A, S, D");
	write("Look: Arrow keys");
	scrtxt.setTextFormat(txformat);
	
	r_framecount = 1;
	r_zframe = 1;
	r_zmmframe = 0x400000;
	
	r_images = new Vector<ImgName>();
	
	VectorSet(#{vec_origin},0,0,0);
	VectorSet(#{vieworg},128.06250,-319.93750,64.062500);
	VectorSet(#{viewangles},0,135.00000,0);
	fov_x = 90.0;
	fov_y = 73.739792;
	scr_width = RESH;
	scr_height = RESV;
	scr_x = scr_y = 0;
	xOrigin = XCENTERING;
	yOrigin = YCENTERING;
	r_aliasuvscale = 1.0;
	
	#{view_clipplanes[0].leftedge = 1};
	#{view_clipplanes[1].rightedge = 1};
	#{view_clipplanes[1].leftedge = 0};
	#{view_clipplanes[2].leftedge = 0};
	#{view_clipplanes[3].leftedge = 0};
	#{view_clipplanes[0].rightedge = 0};
	#{view_clipplanes[2].rightedge = 0};
	#{view_clipplanes[3].rightedge = 0};
	
	R_ViewChanged ();
	
	basespan_p = #{basespans};
	max_span_p = #{&basespans[MAXSPANS - scr_width]};
	#{surf_max = &surfaces[NUMSTACKSURFACES]};
	#{edge_max = &r_edges[NUMSTACKEDGES]};
	
	Init_Edgetables();
	
	R_LoadLight16();
	
	RCE_pv0 = #{RCE_v0.p};
	RCE_pv1 = #{RCE_v1.p};
	RCE_clipvert = #{RCE_v2.p};
	
	__m__.position = #{adivtab};
	__m__.writeBytes(haxe.Resource.getBytes("adivtab").getData(),0,2048);
	
	r_viewcluster = -1;
	r_oldviewcluster = -2;
	r_visframecount = 1;
	
	Con_Printf (PRINT_ALL, "ref_soft version: \"REF_VERSION\"");
	
	return;
}


private function R_LoadLight16() {
	
	var ptr : Int = 0;
	var div : Float = 2.0/255;
	var mul : Float;
	var colr : Int, colb : Int;
	
	for (i in 0...256) {
		mul = i*div;
		for (r in 0...32) {
			colr = Math.floor( (r<<3)*mul );
			if (colr > 255) colr = 255;
			for (b in 0...32) {
				colb = Math.floor( (b<<3)*mul );
				if (colb > 255) colb = 255;
				Memory.setI16( ptr, colr<<8 | colb );
				ptr += 2;
			}
		}
	}
	
	ptr = DRAWOFS0;
	
	for (r in 0...256) {
		for (i in 0...256) {
			mul = i*div;
			colr = Math.floor( r*mul );
			if (colr > 255) colr = 255;
			Memory.setByte( ptr++, colr );
		}
	}
	
	
	
}


/*
@@@@@@@@@@@@@@@@
R_RenderFrame
@@@@@@@@@@@@@@@@
*/
private function R_RenderFrame ()
{
	R_SetupFrame ();
	
	currentmodel = #{&models[0]};
	TransformVector (#{r_origin}, #{transformed_modelorg});
	
	VectorCopy(#{r_origin}, #{modelorg});
	
	R_MarkLeaves ();
	R_BeginEdgeFrame ();
	R_RenderWorld();
	
	R_DrawEntitiesOnList();
	
	R_ScanEdges ();
	
	__m__.position = DRAWOFS1;
	bmp.bitmapData.setPixels(bmp.bitmapData.rect,__m__);
}

private function R_DrawEntitiesOnList() {
	for (i in 0...(RESH*RESV)) { Memory.setI32(DRAWOFS1+(i<<2),0xFFFFFFFF); }
	VectorSubtract (#{r_origin}, #{s_pmdl->origin}, #{modelorg});
	R_AliasDrawModel ();
}

/*
===============
R_MarkLeaves

Mark the leaves and nodes that are in the PVS for the current
cluster
===============
*/
private function R_MarkLeaves ()
{
	#{d| byte	*vis}
	#{d| mnode_t	*node}
	#{d| int		i, cluster}
	#{d| mleaf_t	*leaf}

	if (r_oldviewcluster == r_viewcluster) // && r_viewcluster != -1) init old to -2;
		return;

	r_visframecount++;
	r_oldviewcluster = r_viewcluster;

	if (r_viewcluster == -1)
	{
		// mark everything
		leaf = #{currentmodel->leafs};
		for (i in 0...#{currentmodel->numleafs}) {
			#{leaf->visframe = r_visframecount};
			leaf += #{sizeof(mleaf_t)};
		}
		node = #{currentmodel->nodes};
		for (i in 0...#{currentmodel->numnodes}) {
			#{node->visframe = r_visframecount};
			node += #{sizeof(mnode_t)};
		}
		return;
	}

	vis = Mod_ClusterPVS (r_viewcluster);
	leaf = #{currentmodel->leafs};
	
	for (i in 0...#{currentmodel->numleafs})
	{
		cluster = #{leaf->cluster};
		if (cluster != -1 && #{vis[#[cluster>>3]#]} & (1<<(cluster&7)) != 0)
		{
			node = leaf;
			do
			{
				if (#{node->visframe} == r_visframecount)
					break;
				#{node->visframe = r_visframecount};
				#{node = node->parent};
			} while (node > 4);
		}
		leaf += #{sizeof(mleaf_t)};
	}
}

